/**
 * 场景 - L5
 * @author lonphy
 * @version 0.1
 */
(function(L5) {
	"use strict";
	class Scenes {
		/**
		 * 场景构造器
		 * @param fov {Number} 垂直视角
		 * @param ratio {Number} 视截体长宽比
		 * @param near {Number} 近截面
		 * @param far {Number} 远截面
		 */
		constructor(fov, ratio, near, far) {
			this.camera = null;	// 摄像机
			this.objects = new Set();	// 场景物体
			this.lights = new Map();	// 光源, 多个
			this._bgColor = new L5.Vec4(0,0,0,1);	// 背景颜色；

			this.fov = fov;
			this.ratio = ratio;
			this.near = near;
			this.far = far;
			this.proMatrix = L5.Matrix.perspective(fov,ratio, near, far);
		}
		/**
		 * 场景缩放
		 * @param aspect {Number} 缩放累加系数
		 */
		zoom(aspect) {
			let fov = this.fov;
			if(fov >= 1 && fov <= 180) {
				fov -= aspect;
			}
			if(fov <= 1) {
				fov = 1;
			}
			if(fov >= 179.99) {
				fov = 179.99;
			}
			this.fov = fov;
			this.proMatrix = L5.Matrix.perspective(fov, this.ratio, this.near, this.far);
		}
		/**
		 * 设置场景背景颜色
		 * @param color {L5.Vec4}
		 */
		set bgColor(color) {
			this._bgColor.r = color.r;
			this._bgColor.g = color.g;
			this._bgColor.r = color.r;
			this._bgColor.a = color.a;
		}
		/**
		 * 设置场景像机
		 * @param camera {L5.Camera}
		 */
		setCamera(camera) {
			camera.scenes = this;
			this.camera = camera;
		}
		/**
		 * 添加3D物体
		 * @param obj {L5.Object}
		 */
		addObject(obj) {
			obj.scenes = this;
			this.objects.add(obj);
		}
		/**
		 * 添加光源
		 * @param light {L5.Light}
		 */
		addLight(light) {
			light.scenes = this;
			if (light instanceof L5.PointLight) {
				this.lights.set('point', light);
			}
			else if (light instanceof L5.ParallelLight) {
				this.lights.set('parallel', light);
			}
			else if (light instanceof L5.Light) {
				this.lights.set('ambient', light);
			}
		}
		/**
		 * 渲染场景
		 * @param gl {WebGLRenderingContext}
		 * @param fps {Number} 当前帧频
		 * @param time {Number} 累计运行时间
		 */
		render(gl, fps, time) {
			gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
			this.camera.update(gl, fps, time);

			for(let l of this.lights){
				l.update&&l.update(gl, fps, time);
			}
			for(let o of this.objects){
				o.draw(gl, fps, time);
			}
		}

		applyLights(gl, uniforms) {
			// 环境光
			gl.uniform3fv(uniforms.uLAmbient, this.lights.get('ambient').color);

			// 平行光
			let par = this.lights.get('parallel');
			if (par) {
				gl.uniform3fv(uniforms.uLParallelDir, par.direction);
				gl.uniform3fv(uniforms.uLParallelColor, par.color);
			}

			// 点光源
			let point = this.lights.get('point');
			if (point) {
				gl.uniform3fv(uniforms.uLPointPos, point.position);
				gl.uniform3fv(uniforms.uLPointColor, point.color);
			}
		}
	}
	L5.Scenes = Scenes;
})(window.L5);